Skip to content

planner: support index_join_first() hint to prefer index join#66596

Open
fixdb wants to merge 3 commits intopingcap:masterfrom
fixdb:indexjoinfirst
Open

planner: support index_join_first() hint to prefer index join#66596
fixdb wants to merge 3 commits intopingcap:masterfrom
fixdb:indexjoinfirst

Conversation

@fixdb
Copy link
Contributor

@fixdb fixdb commented Feb 28, 2026

What problem does this PR solve?

Issue Number: close #61501

Problem Summary:

What changed and how does it work?

support index_join_first() hint to prefer index join

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

Add  index_join_first() hint to prefer index join.

Summary by CodeRabbit

  • New Features

    • Added INDEX_JOIN_FIRST optimizer hint to prefer index-based join methods during planning and join reordering; it is a no-argument hint, applies across joins, and respects table-level INL_* hints and existing join hint interactions.
  • Tests

    • Added comprehensive tests validating INDEX_JOIN_FIRST behavior across simple, multi-way, and mixed-hint join scenarios.

@ti-chi-bot ti-chi-bot bot added do-not-merge/needs-tests-checked release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Feb 28, 2026
@pantheon-ai
Copy link

pantheon-ai bot commented Feb 28, 2026

Review Complete

Findings: 1 issues
Posted: 1
Duplicates/Skipped: 0

@ti-chi-bot ti-chi-bot bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Feb 28, 2026
@ti-chi-bot
Copy link

ti-chi-bot bot commented Feb 28, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign benmeadowcroft, d3hunter, winoros for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tiprow
Copy link

tiprow bot commented Feb 28, 2026

Hi @fixdb. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot bot added the sig/planner SIG: Planner label Feb 28, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Walkthrough

Adds a new statement-level optimizer hint INDEX_JOIN_FIRST from parser token through PlanHints into join reordering and physical plan selection to prefer index-based join implementations when applicable.

Changes

Cohort / File(s) Summary
Parser tokens & grammar
pkg/parser/hintparser.y, pkg/parser/ast/misc.go, pkg/parser/misc.go
Introduce INDEX_JOIN_FIRST token and nullary hint recognition; map token into hint token map so the parser accepts the new hint name.
Hint infrastructure
pkg/util/hint/hint.go
Add HintIndexJoinFirst constant, PlanHints.IndexJoinFirst bool, and PreferIndexJoinFirst flag; parse and populate PlanHints with the new hint.
Logical join handling
pkg/planner/core/operator/logicalop/logical_join.go
Wire statement-level IndexJoinFirst into join hint flags (set PreferIndexJoinFirst) and mask this soft preference during join-type conflict checks.
Physical plan selection
pkg/planner/core/exhaust_physical_plans.go
Prefer index-join physical plans when IndexJoinFirst is active and no table-specific INL_* hints conflict (gating added in preferIndexJoinFamily).
Join reorder propagation
pkg/planner/core/rule_join_reorder.go
Add indexJoinFirstHints *h.PlanHints to basicJoinGroupInfo; capture, thread, and reapply the hint across join-group extraction and new join construction.
Tests
pkg/planner/core/casetest/hint/hint_test.go
Add TestIndexJoinFirstHint (plus strings import) to verify INDEX_JOIN_FIRST behavior across 2- and 3-way joins and interactions with other hints.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Parser
    participant Planner
    participant Physical

    Client->>Parser: SQL with INDEX_JOIN_FIRST hint
    Parser->>Parser: tokenize/recognize hint -> PlanHints(IndexJoinFirst=true)
    Parser->>Planner: AST + PlanHints
    Planner->>Planner: set PreferIndexJoinFirst in join hint flags
    Planner->>Physical: exhaust_physical_plans(with PreferIndexJoinFirst)
    Physical->>Physical: preferIndexJoinFamily favors index-join variants
    Physical-->>Planner: chosen physical plan (index-join when applicable)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

size/L

Suggested reviewers

  • qw4990
  • terry1purcell
  • guo-shaoge

Poem

🐰
I found a hint beneath the ground,
INDEX_JOIN_FIRST — a joyful sound.
From token to plan I hop and cheer,
Index joins first, the path is clear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: adding support for the index_join_first() hint to prefer index joins during planning.
Description check ✅ Passed The PR description includes the issue number (close #61501), a brief problem summary, what changed, completed test checklist items, and a release note. It follows the template structure with all critical sections filled.
Linked Issues check ✅ Passed The PR fully implements the requirement from issue #61501 by adding a hint (index_join_first) that instructs the planner to prefer IndexJoin over other join types, with comprehensive support across parser, planner, and hint handling.
Out of Scope Changes check ✅ Passed All changes are directly within scope of implementing the index_join_first hint: parser updates, planner logic, hint infrastructure, and comprehensive tests. No extraneous changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Command failed


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@fixdb
Copy link
Contributor Author

fixdb commented Feb 28, 2026

/ok-to-test

@ti-chi-bot ti-chi-bot bot added the ok-to-test Indicates a PR is ready to be tested. label Feb 28, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
pkg/util/hint/hint.go (1)

132-134: Align wording with actual soft-preference semantics.

The comment says “always prefer”, but the implementation and surrounding docs describe a “when possible” preference.

✏️ Suggested wording tweak
-	// HintIndexJoinFirst is a SQL hint to indicate the optimizer should always prefer index join over other join types.
+	// HintIndexJoinFirst is a SQL hint to indicate the optimizer should prefer index join over other join types when possible.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/util/hint/hint.go` around lines 132 - 134, Update the doc comment for the
HintIndexJoinFirst constant to reflect its soft-preference semantics (i.e.,
prefer index join when possible rather than "always prefer"); modify the comment
above HintIndexJoinFirst to say it indicates the optimizer should prefer index
joins when feasible and that it does not force them or take parameters, keeping
the constant name and behavior unchanged so readers understand it is a
best-effort preference.
pkg/planner/core/operator/logicalop/logical_join.go (1)

1710-1715: Align index_join_first assignment with its stated precedence contract

On Line 1713, the code sets PreferIndexJoinFirst unconditionally, while the comment says it should be set only when no side-specific index-join hint is forced. Adding that guard here would keep precedence explicit and less brittle.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/operator/logicalop/logical_join.go` around lines 1710 -
1715, The assignment of p.PreferJoinType |= utilhint.PreferIndexJoinFirst when
hintInfo.IndexJoinFirst is true should be guarded so it only applies if no
side-specific index-join hint is forced; update the block around
hintInfo.IndexJoinFirst to check that neither left nor right table-specific
index-join force flags are set (e.g., the corresponding hintInfo fields that
indicate a forced index join for a particular side) before setting
p.PreferJoinType, leaving other behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/planner/core/casetest/hint/hint_test.go`:
- Around line 456-521: The test's plan-type matcher only treats "IndexJoin" and
"IndexHashJoin" as valid, causing false failures when plans use
"IndexMergeJoin"; update each check that sets hasIndexJoin by expanding the
condition to also accept "IndexMergeJoin" (look for occurrences of hasIndexJoin
variable and the planType checks in hint_test.go) so the test recognizes all
index-join-family plans as success.

In `@pkg/planner/core/exhaust_physical_plans.go`:
- Around line 2272-2276: The current block in the INDEX_JOIN_FIRST path returns
true for any index-join family before honoring explicit INL_* preferences;
change the logic in the p.PreferAny(h.PreferIndexJoinFirst) branch to first call
getIndexJoinSideAndMethod(physicPlan) to determine isIndexJoin, and only return
true when isIndexJoin is true AND none of the explicit INL preferences are set
(i.e. !p.PreferAny(h.PreferInlJoin, h.PreferInlHashJoin, h.PreferInlMergeJoin));
otherwise fall through so explicit INL_JOIN/INL_HASH_JOIN/INL_MERGE_JOIN
preferences can still decide.

---

Nitpick comments:
In `@pkg/planner/core/operator/logicalop/logical_join.go`:
- Around line 1710-1715: The assignment of p.PreferJoinType |=
utilhint.PreferIndexJoinFirst when hintInfo.IndexJoinFirst is true should be
guarded so it only applies if no side-specific index-join hint is forced; update
the block around hintInfo.IndexJoinFirst to check that neither left nor right
table-specific index-join force flags are set (e.g., the corresponding hintInfo
fields that indicate a forced index join for a particular side) before setting
p.PreferJoinType, leaving other behavior unchanged.

In `@pkg/util/hint/hint.go`:
- Around line 132-134: Update the doc comment for the HintIndexJoinFirst
constant to reflect its soft-preference semantics (i.e., prefer index join when
possible rather than "always prefer"); modify the comment above
HintIndexJoinFirst to say it indicates the optimizer should prefer index joins
when feasible and that it does not force them or take parameters, keeping the
constant name and behavior unchanged so readers understand it is a best-effort
preference.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 25ac994 and 400a7b7.

📒 Files selected for processing (9)
  • pkg/parser/ast/misc.go
  • pkg/parser/hintparser.go
  • pkg/parser/hintparser.y
  • pkg/parser/misc.go
  • pkg/planner/core/casetest/hint/hint_test.go
  • pkg/planner/core/exhaust_physical_plans.go
  • pkg/planner/core/operator/logicalop/logical_join.go
  • pkg/planner/core/rule_join_reorder.go
  • pkg/util/hint/hint.go

@codecov
Copy link

codecov bot commented Feb 28, 2026

Codecov Report

❌ Patch coverage is 96.15385% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.5452%. Comparing base (0b23ce6) to head (6a94934).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #66596        +/-   ##
================================================
- Coverage   77.6584%   77.5452%   -0.1133%     
================================================
  Files          2008       2009         +1     
  Lines        549335     549429        +94     
================================================
- Hits         426605     426056       -549     
- Misses       121059     121665       +606     
- Partials       1671       1708        +37     
Flag Coverage Δ
unit 76.0920% <96.1538%> (-0.2239%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 56.7974% <ø> (ø)
parser ∅ <ø> (∅)
br 60.8571% <ø> (-0.0284%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pantheon-ai
Copy link

pantheon-ai bot commented Mar 4, 2026

Review Complete

Findings: 0 issues
Posted: 0
Duplicates/Skipped: 0

ℹ️ Learn more details on Pantheon AI.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/util/hint/hint.go (1)

966-967: Consider adding duplicate hint warning for consistency.

Other hints in this function (e.g., straightJoinHintCnt) track multiple occurrences and emit warnings when defined more than once. The index_join_first hint doesn't track or warn about duplicates. While this is a minor issue since the hint is idempotent (setting true multiple times has no effect), adding a counter and warning would be consistent with the existing pattern.

♻️ Optional: Add duplicate hint warning
// Add counter near other hint counters (around line 794)
var indexJoinFirstHintCnt int

// In the switch case:
case HintIndexJoinFirst:
    indexJoinFirstHintCnt++
    indexJoinFirst = true

// After parsing loop, add warning check:
if indexJoinFirstHintCnt > 1 {
    warnHandler.SetHintWarning("INDEX_JOIN_FIRST() is defined more than once, only the last definition takes effect")
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/util/hint/hint.go` around lines 966 - 967, The HintIndexJoinFirst branch
currently sets indexJoinFirst = true but does not track duplicates; add an
integer counter (e.g., indexJoinFirstHintCnt) alongside the other hint counters,
increment it in the case for HintIndexJoinFirst, and after parsing check if
indexJoinFirstHintCnt > 1 and call warnHandler.SetHintWarning with a message
like "INDEX_JOIN_FIRST() is defined more than once, only the last definition
takes effect" to mirror the duplicate-hint behavior used for straightJoinHintCnt
and others.
pkg/planner/core/operator/logicalop/logical_join.go (1)

1710-1715: Comment and behavior are slightly out of sync.

The comment says the flag is set only when no side is forced, but the code sets it unconditionally and defers precedence handling downstream. Consider aligning the comment to avoid future confusion.

✏️ Suggested comment-only adjustment
-	// index_join_first is a statement-level hint that prefers index join on all joins.
-	// It is applied after table-specific hints; if a table-specific index join hint was set,
-	// it is already covered. We only set the flag here when no specific side is forced.
+	// index_join_first is a statement-level hint that prefers index join on all joins.
+	// It is applied after table-specific hints. Precedence vs. explicit INL_* hints
+	// is resolved downstream during physical-plan preference checks.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/operator/logicalop/logical_join.go` around lines 1710 -
1715, The comment above the index_join_first handling is inaccurate: it claims
the flag is set only when no side is forced, but the code unconditionally sets
p.PreferJoinType |= utilhint.PreferIndexJoinFirst when hintInfo.IndexJoinFirst
is true and relies on downstream precedence resolution; update the comment to
state that IndexJoinFirst is applied here regardless of side and that precedence
between table-specific hints and this statement-level hint is resolved later
(mentioning hintInfo.IndexJoinFirst, p.PreferJoinType, and
utilhint.PreferIndexJoinFirst).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/planner/core/casetest/hint/hint_test.go`:
- Around line 526-548: The current checkPlan helper only asserts the operator
kind and can miss whether the chosen inner side matches the
INL_JOIN(t1)/INL_HASH_JOIN(t1) hint; modify checkPlan (or add a new helper used
in these cases) to also assert the inner table is t1 by checking the plan row
text for the inner-side marker (e.g., ensure the plan string contains both the
operator name "IndexJoin"/"IndexHashJoin" and an explicit inner reference to
"t1" or the planner's inner-side notation), then update the two calls that
assert INL_JOIN(t1) and INL_HASH_JOIN(t1) to use this tightened check so both
operator and inner table are validated.

---

Nitpick comments:
In `@pkg/planner/core/operator/logicalop/logical_join.go`:
- Around line 1710-1715: The comment above the index_join_first handling is
inaccurate: it claims the flag is set only when no side is forced, but the code
unconditionally sets p.PreferJoinType |= utilhint.PreferIndexJoinFirst when
hintInfo.IndexJoinFirst is true and relies on downstream precedence resolution;
update the comment to state that IndexJoinFirst is applied here regardless of
side and that precedence between table-specific hints and this statement-level
hint is resolved later (mentioning hintInfo.IndexJoinFirst, p.PreferJoinType,
and utilhint.PreferIndexJoinFirst).

In `@pkg/util/hint/hint.go`:
- Around line 966-967: The HintIndexJoinFirst branch currently sets
indexJoinFirst = true but does not track duplicates; add an integer counter
(e.g., indexJoinFirstHintCnt) alongside the other hint counters, increment it in
the case for HintIndexJoinFirst, and after parsing check if
indexJoinFirstHintCnt > 1 and call warnHandler.SetHintWarning with a message
like "INDEX_JOIN_FIRST() is defined more than once, only the last definition
takes effect" to mirror the duplicate-hint behavior used for straightJoinHintCnt
and others.

ℹ️ Review info
Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e59936aa-5118-42bf-8f14-015f52deecc5

📥 Commits

Reviewing files that changed from the base of the PR and between 400a7b7 and 43efa1c.

📒 Files selected for processing (9)
  • pkg/parser/ast/misc.go
  • pkg/parser/hintparser.go
  • pkg/parser/hintparser.y
  • pkg/parser/misc.go
  • pkg/planner/core/casetest/hint/hint_test.go
  • pkg/planner/core/exhaust_physical_plans.go
  • pkg/planner/core/operator/logicalop/logical_join.go
  • pkg/planner/core/rule_join_reorder.go
  • pkg/util/hint/hint.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/parser/hintparser.y

Comment on lines +526 to +548
checkPlan := func(query, wantOp string, msg string) {
rows = testKit.MustQuery(query).Rows()
found := false
for _, row := range rows {
if strings.Contains(row[0].(string), wantOp) {
found = true
break
}
}
require.True(t, found, msg)
}
// INL_JOIN(t1): must choose IndexJoin (not IndexHashJoin) with t1 as inner.
checkPlan(
"explain format='brief' select /*+ INDEX_JOIN_FIRST() INL_JOIN(t1) */ t1.a, t2.b from t1 join t2 on t1.a = t2.a",
"IndexJoin",
"INL_JOIN(t1) should win over INDEX_JOIN_FIRST(): IndexJoin with t1 as inner required",
)
// INL_HASH_JOIN(t1): must choose IndexHashJoin (not plain IndexJoin) with t1 as inner.
checkPlan(
"explain format='brief' select /*+ INDEX_JOIN_FIRST() INL_HASH_JOIN(t1) */ t1.a, t2.b from t1 join t2 on t1.a = t2.a",
"IndexHashJoin",
"INL_HASH_JOIN(t1) should win over INDEX_JOIN_FIRST(): IndexHashJoin with t1 as inner required",
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

INL_* regression checks currently miss inner-side validation.

checkPlan only checks the operator kind. It can still pass when the chosen inner side does not match INL_JOIN(t1) / INL_HASH_JOIN(t1) requirements.

✅ Tighten regression intent (method + target table)
-		checkPlan := func(query, wantOp string, msg string) {
+		checkPlan := func(query, wantOp, wantInnerTbl string, msg string) {
 			rows = testKit.MustQuery(query).Rows()
 			found := false
 			for _, row := range rows {
-				if strings.Contains(row[0].(string), wantOp) {
+				planType := row[0].(string)
+				rowText := strings.ToLower(strings.TrimSpace(strings.Join([]string{
+					planType,
+					row[len(row)-1].(string),
+				}, " ")))
+				if strings.Contains(planType, wantOp) && strings.Contains(rowText, strings.ToLower(wantInnerTbl)) {
 					found = true
 					break
 				}
 			}
 			require.True(t, found, msg)
 		}
@@
-		checkPlan(
+		checkPlan(
 			"explain format='brief' select /*+ INDEX_JOIN_FIRST() INL_JOIN(t1) */ t1.a, t2.b from t1 join t2 on t1.a = t2.a",
 			"IndexJoin",
+			"t1",
 			"INL_JOIN(t1) should win over INDEX_JOIN_FIRST(): IndexJoin with t1 as inner required",
 		)
@@
-		checkPlan(
+		checkPlan(
 			"explain format='brief' select /*+ INDEX_JOIN_FIRST() INL_HASH_JOIN(t1) */ t1.a, t2.b from t1 join t2 on t1.a = t2.a",
 			"IndexHashJoin",
+			"t1",
 			"INL_HASH_JOIN(t1) should win over INDEX_JOIN_FIRST(): IndexHashJoin with t1 as inner required",
 		)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/casetest/hint/hint_test.go` around lines 526 - 548, The
current checkPlan helper only asserts the operator kind and can miss whether the
chosen inner side matches the INL_JOIN(t1)/INL_HASH_JOIN(t1) hint; modify
checkPlan (or add a new helper used in these cases) to also assert the inner
table is t1 by checking the plan row text for the inner-side marker (e.g.,
ensure the plan string contains both the operator name
"IndexJoin"/"IndexHashJoin" and an explicit inner reference to "t1" or the
planner's inner-side notation), then update the two calls that assert
INL_JOIN(t1) and INL_HASH_JOIN(t1) to use this tightened check so both operator
and inner table are validated.

@pantheon-ai
Copy link

pantheon-ai bot commented Mar 4, 2026

Review Complete

Findings: 0 issues
Posted: 0
Duplicates/Skipped: 0

ℹ️ Learn more details on Pantheon AI.

Copy link

@pantheon-ai pantheon-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Code looks good. No issues found.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 4, 2026

[FORMAT CHECKER NOTIFICATION]

Notice: To remove the do-not-merge/needs-tests-checked label, please finished the tests then check the finished items in description.

For example:

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

📖 For more info, you can check the "Contribute Code" section in the development guide.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
pkg/planner/core/rule_join_reorder.go (1)

723-728: Potential HintInfo overwrite when combining table-specific and statement-level hints.

SetNewJoinWithHint (line 722) may set join.HintInfo from joinMethodHintInfo for table-specific hints. Then line 727 unconditionally overwrites it with indexJoinFirstHints. If a query uses both INDEX_JOIN_FIRST() and table-specific hints like HASH_JOIN(t1), the table-specific HintInfo context is lost, which could affect warning generation for unused hints.

Consider merging hint info rather than overwriting, or at minimum documenting this precedence behavior. That said, the existing SetNewJoinWithHint already exhibits an overwrite pattern between left/right children, so this follows established behavior.

Potential improvement (optional)

If both hint sources should be preserved:

 	if s.indexJoinFirstHints != nil {
 		join.PreferJoinType |= h.PreferIndexJoinFirst
-		join.HintInfo = s.indexJoinFirstHints
+		// Only set HintInfo if not already set by table-specific hints
+		if join.HintInfo == nil {
+			join.HintInfo = s.indexJoinFirstHints
+		}
 	}

Alternatively, document the intentional precedence if INDEX_JOIN_FIRST should take priority.


ℹ️ Review info
Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d431fa77-5fe7-4dd4-9388-1c350f66c615

📥 Commits

Reviewing files that changed from the base of the PR and between 43efa1c and 6a94934.

📒 Files selected for processing (1)
  • pkg/planner/core/rule_join_reorder.go

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 4, 2026

@fixdb: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
idc-jenkins-ci-tidb/check_dev 6a94934 link true /test check-dev
pull-integration-realcluster-test-next-gen 6a94934 link true /test pull-integration-realcluster-test-next-gen
idc-jenkins-ci-tidb/unit-test 6a94934 link true /test unit-test

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/needs-tests-checked ok-to-test Indicates a PR is ready to be tested. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

planner: support a hint or var like index-join-first to indicate the planner to prefer IndexJoin over other joins

1 participant